<?php
namespace App\Common\Cla\ClaBase\Traits\Common\MagicGather\Set;

use App\Common as com;
use App\Common\Cla\ClaBase\Traits\Common\MagicGather as cla_MagicGather;
use think\facade\App;

/**
 * 魔术集->set->主
 * 说明：
 * 	1.类必须带有 "_mgSetOfAllow" 或" _mgGetSetOfAllow"，[array] 设置允许读的属性。格式[ 'msgSaltKey', ... ] ['all']允许所有
 *  2.优先执行"$this->_mgSetOfXxx()"的返回值，其次设置类的属性
 *  3.本魔术方法对于不在 "_mgSetOfAllow" 或" _mgGetSetOfAllow" 中的属性，都不允许设置
 */
class Main extends cla_MagicGather\Base {
	
	/** 魔术方法事件名称 */
	private $eventSid_Module = 'set_main';
	
	/**
	 *
	 * @param obj $son_class_this MagicGather所在的this
	 */
	public function __construct( $magic_gather_this ){
		parent::__construct( $magic_gather_this );
		// 注册魔术方法get回调
		$this->magicGatherApi->registerMagicEvent( 'set', $this->eventSid_Module, function( $name, $value ){
			return $this->eventCallback( $name, $value );
		} );
	}
	
	/**
	 * 魔术事件回调
	 * @param str $property_name 属性名
	 * @param mixed $value 属性值
	 * @return bool [false]没设置 [true]已设置
	 */
	private function eventCallback( $property_name, $value ){
		// 检查是否允许外部设置
		if( ! $this->isAllowExternalSet( $property_name ) && ! $this->isAllowExternalGetSet( $property_name ) ){
			// 如果存在则不允许修改
			if( $this->magicGatherApi->propertyExists( $property_name ) ){
				return false;
			}
		}
		// 调用预定义方法获取属性值
		$callback_str = '_mgSetOf' . com\Lib\Fun\Str::parseName( $property_name, 1, true );
		if( $this->magicGatherApi->methodExists( $callback_str ) ){
			$this->magicGatherApi->methodCall( $callback_str, [ $value ] );
			return true;
		}
		// 直接设置类的属性值
		$this->magicGatherApi->propertySet( $property_name, $value );
		return true;
	}
	
	/**
	 * 检查指定属性是否允许外部设置
	 * @param str $property_name 属性名
	 * @return bool [false]不允许 [true]允许
	 */
	private function isAllowExternalSet( $property_name ){
		//
		if( ! $this->magicGatherApi->propertyExists( '_mgSetOfAllow' ) ) return false;
		$magic_gather_set_allow = $this->magicGatherApi->propertyGet( '_mgSetOfAllow' );
		if( $magic_gather_set_allow == 'all' ) return true; // 允许设置所有
		// 检查可以读的属性
		return in_array( $property_name, $magic_gather_set_allow ?? [] );
	}
	
	/**
	 * 检查指定属性是否允许外部设置和读取
	 * @param str $property_name 属性名
	 * @return bool [false]不允许 [true]允许
	 */
	private function isAllowExternalGetSet( $property_name ){
		//
		if( ! $this->magicGatherApi->propertyExists( '_mgGetSetOfAllow' ) ) return false;
		$magic_gather_get_set_allow = $this->magicGatherApi->propertyGet( '_mgGetSetOfAllow' );
		if( $magic_gather_get_set_allow == 'all' ) return true; // 允许读取所有
		// 检查可以读的属性
		return in_array( $property_name, $magic_gather_get_set_allow?? [] );
	}
	
}
